const { Service } = require("egg");
const Cos = require("cos-nodejs-sdk-v5");
const path = require("path");
const STS = require('qcloud-cos-sts');
const fs = require('fs');

const SecretId = "AKIDtw7GG8rRtEQUO9qMiuvi1Dc6WoxypZG0";
const SecretKey = "kNuKcnyzzsdFlAQXUJ9tW4Uny1vhLsHX";

const CosInstance = new Cos({
  SecretId,
  SecretKey,
});
const bucket = "buss-asso-1253854551";
const region = "ap-beijing";
function getMimeType(filename) {
  const ext = path.extname(filename).toLowerCase();
  console.log(ext, 'ext')
  switch (ext) {
    case ".mp4":
      return "video/mp4";
    case ".webm":
      return "video/webm";
    case ".mov":
      return "video/quicktime";

    case ".jpg":
    case ".jpeg":
      return "image/jpeg";
    case ".png":
      return "image/png";
    case ".gif":
      return "image/gif";
    case ".bmp":
      return "image/bmp";
    case ".svg":
      return "image/svg+xml";

    case ".pdf":
      return "application/pdf";
    case ".doc":
      return "application/msword";
    case ".docx":
      return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
    case ".xls":
      return "application/vnd.ms-excel";
    case ".xlsx":
      return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
    case ".ppt":
      return "application/vnd.ms-powerpoint";
    case ".pptx":
      return "application/vnd.openxmlformats-officedocument.presentationml.presentation";

    case ".zip":
      return "application/zip";
    case ".rar":
      return "application/x-rar-compressed";
    case ".tar":
    case ".gz":
    case ".tgz":
      return "application/gzip";

    // 添加更多类型...
    default:
      // 如果未知类型，可以尝试自动检测或使用默认值
      return "application/octet-stream";
  }
}

class ossService extends Service {
  generateTemporaryCredentials() {

    const config = {
      secretId: SecretId,
      secretKey: SecretKey,
      proxy: '',
      durationSeconds: 1800,
      endpoint: 'sts.tencentcloudapi.com',
      bucket,
      region,
      allowPrefix: 'assets/*',
      allowActions: [
        'name/cos:PutObject',
        'name/cos:PostObject',
        'name/cos:InitiateMultipartUpload',
        'name/cos:ListMultipartUploads',
        'name/cos:ListParts',
        'name/cos:UploadPart',
        'name/cos:CompleteMultipartUpload'
      ],
    };

    const shortBucketName = config.bucket.substr(0, config.bucket.lastIndexOf('-'));
    const appId = config.bucket.substr(1 + config.bucket.lastIndexOf('-'));
    const policy = {
      'version': '2.0',
      'statement': [{
        'action': config.allowActions,
        'effect': 'allow',
        'principal': { 'qcs': ['*'] },
        'resource': [
          'qcs::cos:' + config.region + ':uid/' + appId + ':prefix//' + appId + '/' + shortBucketName + '/' + config.allowPrefix,
        ],
      }],
    };
    return new Promise((resolve, reject) => {
      STS.getCredential({
        secretId: config.secretId,
        secretKey: config.secretKey,
        proxy: config.proxy,
        durationSeconds: config.durationSeconds,
        endpoint: config.endpoint,
        policy: policy,
      }, function (err, tempKeys) {
        if (!err) {
          resolve({
            bucket,
            region,
            ...tempKeys,
          })
        } else {
          throw err
        }
      });
    })
  }

  async upload(fileData, key) {
    const mimeType = getMimeType(key); // 获取Content-Type
    try {
      const data = await CosInstance.putObject({
        Bucket: bucket,
        Region: region,
        Body: fileData,
        Key: key,
        ContentType: mimeType,
      });
      return data;
    } catch (error) {
      this.logger.error(error);
      throw error; // 重新抛出错误，以便外部调用者可以处理
    }
  }

  async baseUpload(filePath, key) {
    const mimeType = getMimeType(key); // 获取Content-Type

    try {
      const data = await CosInstance.uploadFile({
        Bucket: bucket,
        Region: region,
        Key: key,
        FilePath: filePath,
        ContentType: mimeType,
      });
      this.logger.info(data, '上传成功');
      return "https://" + data.Location;
    } catch (error) {
      this.logger.error(error);
      throw error; // 重新抛出错误，以便外部调用者可以处理
    }
  }


  async uploadDirectory(directoryPath, cosBaseKey) {
    try {
      const files = fs.readdirSync(directoryPath);
      const uploadResults = [];
      const promises = [];

      for (const file of files) {
        const filePath = path.join(directoryPath, file);
        const stats = fs.statSync(filePath);

        if (stats.isDirectory()) {
          // 递归上传子目录，并收集结果
          const subResultsPromise = this.uploadDirectory(filePath, `${cosBaseKey}${file}/`);
          promises.push(subResultsPromise.then(subResults => {
            uploadResults.push(...subResults);
          }));
        } else {
          const relativePath = path.relative(directoryPath, filePath);
          const cosKey = `${cosBaseKey}${relativePath}`;
          const uploadResultPromise = this.baseUpload(filePath, cosKey);
          promises.push(uploadResultPromise.then(result => {
            uploadResults.push({
              fileName: file,
              url: result
            });
          }));
        }
      }

      await Promise.all(promises); // 等待所有上传完成
      return uploadResults; // 返回所有上传操作的结果，包括原始文件名和上传后的文件名
    } catch (error) {
      this.logger.error(error);
      throw error; // 重新抛出错误，以便外部调用者可以处理
    }
  }

  async delete(filepath) {
    try {
      const params = {
        Bucket: bucket,
        Region: region,
        Key: filepath,
      };
      const data = await CosInstance.deleteObject(params);

      return data;
    } catch (err) {
      this.logger.error(err);
      throw err; // 重新抛出错误，以便外部调用者可以处理
    }
  }
}
module.exports = ossService;
